// 环境判断与基础URL配置
const isDevelopment = process.env.NODE_ENV === 'development'
const baseUrl = isDevelopment 
  ? 'https://ai.aiyuhua.com/ky/KM/chat/call'  // 开发环境API地址
  : 'https://ai.aiyuhua.com/ky/KM/chat/stream'  // 生产环境API地址

// 应用版本号 - 第二个公共参数
const appVersion = '1.0.0'

// 请求队列管理，用于取消请求
const requestQueue = new Map()

/**
 * 生成唯一请求ID
 * @param {string} url 请求URL
 * @param {string} method 请求方法
 * @returns {string} 唯一ID
 */
const generateRequestId = (url, method) => {
  return `${method}-${url}-${Date.now()}`
}

/**
 * 获取公共请求参数
 * @returns {Object} 包含所有公共参数的对象
 */
const getCommonParams = () => {
  // 从本地存储获取token
  const token = uni.getStorageSync('token') || ''
  
  // 返回公共参数，可根据需要扩展
  return {
  //   token,
  //   appVersion,
  //   // 可以添加更多公共参数，如设备信息、时间戳等
  //   timestamp: Date.now(),
	// model: "deepseek-r1:1.5b",
	// stream: false
  }
}

/**
 * 合并公共参数和请求参数
 * @param {Object} params 请求参数
 * @param {string} method 请求方法
 * @returns {Object} 合并后的参数
 */
const mergeParams = (params, method) => {
  const commonParams = getCommonParams()
  
  // GET请求参数拼在URL上，POST/PUT等请求参数放在body里
  if (method.toUpperCase() === 'GET') {
    return { ...commonParams, ...params }
  } else {
    return { ...params, ...commonParams }
  }
}

/**
 * 通用请求工具
 * @param {string} url 请求路径
 * @param {Object} options 请求配置
 * @param {Object} options.param 请求参数
 * @param {string} options.method 请求方法，默认GET
 * @param {Object} options.header 请求头
 * @param {boolean} options.showLoading 是否显示加载中，默认true
 * @param {boolean} options.showError 是否显示错误提示，默认true
 * @param {boolean} options.includeCommonParams 是否包含公共参数，默认true
 * @returns {Promise} 请求结果
 */
export const request = async (url, {
  param = {},
  method = 'GET',
  header = {},
  showLoading = true,
  showError = true,
  includeCommonParams = true
} = {}) => {
  // 生成请求ID
  const requestId = generateRequestId(url, method)
  
  try {
    // 显示加载中
    if (showLoading) {
      uni.showLoading({
        title: '加载中...',
        mask: true
      })
    }
    
    // 合并请求头
    const defaultHeader = {
      "Content-Type": "application/json"
      // token移至参数中，也可以同时在header中携带
      // token: uni.getStorageSync('token') || ''
    }
    const requestHeader = { ...defaultHeader, ...header }
    
    // 合并参数（包含公共参数）
    const requestParams = includeCommonParams 
      ? mergeParams(param, method) 
      : param
    
    // 创建请求取消器
    let abortController = null
    if (uni.canIUse('request.abort')) {
      abortController = new AbortController()
      requestQueue.set(requestId, abortController)
    }
    
    // 发起请求
	const response = await uni.request({
      url: baseUrl + url,
      method,
      data: requestParams,
      header: requestHeader,
      signal: abortController?.signal
    })
    
    // 从请求队列移除
    requestQueue.delete(requestId)
    
    // 隐藏加载中
    if (showLoading) {
      uni.hideLoading()
    }
    
	// 处理请求错误
	if (response.errMsg !== 'request:ok') {
	  if (showError) {
	    uni.showToast({
	      title: response.errMsg || '请求失败',
	      icon: 'none',
	      duration: 3000
	    })
	  }
	  console.error(`[${method}] ${url} 请求失败:`, response)
	  return Promise.reject(response)
	}
	
	let statusCode = response.statusCode
	let data =  response.data
	
	//仅用于大模型
	data.code = 0
	
	console.log("data",data)
	console.log("statusCode",statusCode)
    
    // 打印请求日志
    console.log(`[${method}] ${baseUrl}${url}`, {
      params: requestParams,
      statusCode,
      response: data
    })
    
    // 处理HTTP状态码
    if (statusCode === 200) {
      // 假设后端统一返回格式为 { code, message, data }
      if (data.code === 0) {
        return data
      } else {
        // 业务错误处理
        if (showError) {
          uni.showToast({
            title: data.message || '操作失败',
            icon: 'none',
            duration: 3000
          })
        }
        // 特殊业务码处理
        if (data.code === 401) {
          // 未授权，清除token并跳转到登录页
          uni.removeStorageSync('token')
          uni.navigateTo({
            url: '/pages/login/login'
          })
        }
        return Promise.reject(new Error(data.message || `业务错误: ${data.code}`))
      }
    } else {
      // HTTP错误处理
      const errorMsg = {
        400: '请求参数错误',
        401: '未授权，请登录',
        403: '拒绝访问',
        404: '请求地址不存在',
        500: '服务器内部错误',
        502: '网关错误',
        503: '服务不可用',
        504: '网关超时'
      }[statusCode] || `请求失败: ${statusCode}`
      
      if (showError) {
        uni.showToast({
          title: errorMsg,
          icon: 'none',
          duration: 3000
        })
      }
      
      // 401错误特殊处理
      if (statusCode === 401) {
        uni.removeStorageSync('token')
        uni.navigateTo({
          url: '/pages/login/login'
        })
      }
      
      return Promise.reject(new Error(errorMsg))
    }
  } catch (error) {
    // 捕获其他异常
    requestQueue.delete(requestId)
    if (showLoading) {
      uni.hideLoading()
    }
    
    if (showError && !error.message.includes('abort')) {
      uni.showToast({
        title: error.message || '请求异常',
        icon: 'none',
        duration: 3000
      })
    }
    
    console.error(`[${method}] ${url} 异常:`, error)
    return Promise.reject(error)
  }
}

/**
 * 取消指定请求
 * @param {string} url 请求URL
 * @param {string} method 请求方法
 */
export const cancelRequest = (url, method = 'GET') => {
  for (const [id, controller] of requestQueue.entries()) {
    if (id.startsWith(`${method}-${url}`)) {
      controller.abort()
      requestQueue.delete(id)
    }
  }
}

/**
 * 取消所有请求
 */
export const cancelAllRequests = () => {
  for (const [, controller] of requestQueue.entries()) {
    controller.abort()
  }
  requestQueue.clear()
}

// 快捷请求方法
export const get = (url, param = {}, options = {}) => {
  return request(url, { ...options, param, method: 'GET' })
}

export const post = (url, param = {}, options = {}) => {
  return request(url, { ...options, param, method: 'POST' })
}

export const put = (url, param = {}, options = {}) => {
  return request(url, { ...options, param, method: 'PUT' })
}

export const del = (url, param = {}, options = {}) => {
  return request(url, { ...options, param, method: 'DELETE' })
}
